﻿Imports WiremetModel.Entities.OEM
Imports WiremetModel.Entities
Imports WiremetModel.Specification.GeneralSpecifications
Imports System.Globalization

Public Class WireCertificateOrderLineSelectionDialog

    Public Property SelectedOrderLine As PozycjaZlecenia
    Public Property SelectedMaterial As Material
    Public Property SelectedWires As IList(Of Tracking.Drut)


    Private _unitOfWork As UnitOfWork
    Private _wysylka As Wysylka
    Private _orderLines As Dictionary(Of PozycjaZlecenia, Dictionary(Of Material, List(Of Tracking.Drut)))



    Sub New(ByVal wysylka As Wysylka, ByRef unitOfWork As UnitOfWork)
        InitializeComponent()
        _wysylka = wysylka
        '_unitOfWork = New UnitOfWork()
        _unitOfWork = unitOfWork

        RefreshZlecenieInfo(_wysylka.Zlecenie)
        RefreshWysylkaInfo()
        RefreshPaczkiWysylkiTable()
        RefreshOrderLines()
        RefreshOrderLinesTable()

    End Sub


    Private Sub WireCertificateOrderLineSelectionDialog_FormClosing(ByVal sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
        '_unitOfWork.Dispose()
    End Sub


    Private Sub RefreshZlecenieInfo(ByVal zlecenie As Zlecenie)

        gb_ZlecenieInfo.Text = zlecenie.Klient.NazwaSkrocona + " - " + zlecenie.Numer
        txt_DataUtworzenia.Text = zlecenie.DataUtworzenia.ToShortDateString()
        txt_TerminRealizacji.Text = zlecenie.Termin.ToShortDateString()
        txt_Uwagi.Text = zlecenie.Uwagi

    End Sub


    Private Sub RefreshWysylkaInfo()

        gb_Wysylka.Text = "Wysyłka - " + _wysylka.Numer
        txt_StatusZlecenia.Text = _wysylka.Zlecenie.Status.Nazwa
        txt_StatusWysylki.Text = _wysylka.Zlecenie.StatusWysylki.Nazwa
        txt_DataWysylki.Text = _wysylka.Data.ToShortDateString()
        txt_AdresWysylki.Text = "ul." & _wysylka.Zlecenie.AdresWysylki.Ulica & " " & _wysylka.Zlecenie.AdresWysylki.Numer & vbNewLine &
            _wysylka.Zlecenie.AdresWysylki.KodPocztowy & " " & _wysylka.Zlecenie.AdresWysylki.Miejscowosc & ", " & _wysylka.Zlecenie.AdresWysylki.Kraj

    End Sub

    Private Sub RefreshPaczkiWysylkiTable()

        dgv_PaczkiWysylki.Rows.Clear()
        Dim ordinal As Integer = 1
        For Each paczkaWysylki As PaczkaWysylki In _wysylka.PaczkiWysylki
            dgv_PaczkiWysylki.Rows.Add(ordinal, paczkaWysylki.NumerListuPrzewozowego, paczkaWysylki.Waga.ToString(), paczkaWysylki.FirmaKurierska.Nazwa)
            ordinal += 1
        Next
    End Sub


    Private Sub RefreshOrderLines()

        _orderLines = New Dictionary(Of PozycjaZlecenia, Dictionary(Of Material, List(Of Tracking.Drut)))
        Dim materialProdukcyjnyRepository As New Repository(Of Tracking.MaterialProdukcyjny)(_unitOfWork)

        For Each paczkaWysylki As PaczkaWysylki In _wysylka.PaczkiWysylki
            For Each drutWyslany As DrutWyslany In paczkaWysylki.Druty

                Dim materialProdukcyjnyIdList As New List(Of Integer)

                If Not drutWyslany.Drut.Rodzice.Any() Then
                    materialProdukcyjnyIdList.Add(drutWyslany.Drut.Id)
                End If


                Dim drutsList As New List(Of Tracking.Drut)
                drutsList.Add(drutWyslany.Drut)


                While drutsList.Any()

                    Dim currentDrut As Tracking.Drut = drutsList.First()
                    drutsList.RemoveAt(0)

                    If currentDrut.Rodzice.Any() Then
                        materialProdukcyjnyIdList.AddRange(currentDrut.Rodzice.Where(Function(x) x.WyznMaterialProdukcyjny).Select(Function(x) If(IsNothing(x.DrutRodzic), x.Drut.Id, x.DrutRodzic.Id)))
                        drutsList.AddRange(currentDrut.Rodzice.Where(Function(x) Not x.WyznMaterialProdukcyjny AndAlso Not IsNothing(x.DrutRodzic)).Select(Function(x) x.DrutRodzic))
                    End If
                End While

                Dim materialProdukcyjny As Tracking.MaterialProdukcyjny = Nothing

                While materialProdukcyjny Is Nothing
                    If materialProdukcyjnyIdList.Any() Then
                        Dim materialProdukcyjnyIdSpec As New IdSpecification(Of Tracking.MaterialProdukcyjny)(materialProdukcyjnyIdList.First())
                        materialProdukcyjnyIdList.RemoveAt(0)
                        materialProdukcyjny = materialProdukcyjnyRepository.GetEntityMatching(materialProdukcyjnyIdSpec)
                    Else
                        Dim repoSrepo As New Repository(Of Tracking.MaterialProdukcyjny)(_unitOfWork)
                        materialProdukcyjny = repoSrepo.GetAll().First()
                    End If
                End While


                Dim material As Material = materialProdukcyjny.Material

                Dim pozycjaZlecenia As PozycjaZlecenia = drutWyslany.Drut.PozycjaSchematu.Schemat.PozycjaZlecenia.PozycjaZleceniaOEM

                If Not _orderLines.ContainsKey(pozycjaZlecenia) Then
                    _orderLines.Add(pozycjaZlecenia, New Dictionary(Of Material, List(Of Tracking.Drut)))
                End If

                If Not _orderLines(pozycjaZlecenia).ContainsKey(material) Then
                    _orderLines(pozycjaZlecenia).Add(material, New List(Of Tracking.Drut))
                End If

                _orderLines(pozycjaZlecenia)(material).Add(drutWyslany.Drut)
            Next
        Next
    End Sub

    Private Sub RefreshOrderLinesTable()

        dgv_PozycjeZlecenia.Rows.Clear()
        For Each orderLine As PozycjaZlecenia In _orderLines.Keys.OrderBy(Function(x) x.NumerPozycji)
            For Each material As Material In _orderLines(orderLine).Keys.OrderBy(Function(x) x.Wytop)
                Dim materialLocal As Material = material
                Dim anyWireCertificates As Boolean = orderLine.WireCertificates.Any(Function(x) x.Shipment.Id = _wysylka.Id AndAlso x.Material.Id = materialLocal.Id)
                Dim rowIndex As Integer = dgv_PozycjeZlecenia.Rows.Add(
                    orderLine.Id,
                    orderLine.NumerPozycji,
                    orderLine.Wymiar,
                    orderLine.Gatunek.NazwaAng,
                    material.Wytop,
                    anyWireCertificates,
                    orderLine.TolDolna + "; " + orderLine.TolGorna,
                    orderLine.Wydluzenie,
                    orderLine.WytrzymaloscMin + " - " + orderLine.WytrzymaloscMax,
                    _orderLines(orderLine)(material).Sum(Function(x) x.Kontrola.First().Ilosc).ToString() + " " + orderLine.JednostkaMiary.Jednostka,
                    orderLine.Cena.ToString() + " " + orderLine.Waluta.Nazwa,
                    orderLine.Pakowanie
                )
                dgv_PozycjeZlecenia.Rows(rowIndex).Tag = New Tuple(Of PozycjaZlecenia, Material)(orderLine, material)

                If anyWireCertificates Then
                    dgv_PozycjeZlecenia.Rows(rowIndex).DefaultCellStyle.BackColor = Color.PaleGreen
                End If
            Next
        Next
    End Sub


    Private Sub EnsureOrderLineIsSelected()
        If dgv_PozycjeZlecenia.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz pozycję zlecenia, aby kontynuować.")
        End If
    End Sub


    Private Sub btn_Accept_Click(sender As System.Object, e As System.EventArgs) Handles btn_Accept.Click
        Try
            EnsureOrderLineIsSelected()
            Dim tag As Tuple(Of PozycjaZlecenia, Material) = CType(dgv_PozycjeZlecenia.SelectedRows(0).Tag, Tuple(Of PozycjaZlecenia, Material))

            SelectedWires = _orderLines(tag.Item1)(tag.Item2)
            SelectedOrderLine = tag.Item1
            SelectedMaterial = tag.Item2

            'DialogResult = Windows.Forms.DialogResult.OK
            Dim wireCertificate As WireCertificate = SelectedOrderLine.WireCertificates.FirstOrDefault(Function(x) x.Shipment.Id = _wysylka.Id AndAlso x.Material.Id = SelectedMaterial.Id)
            If wireCertificate Is Nothing Then
                wireCertificate = New WireCertificate()

                Dim chemsList As IList(Of SkladChemiczny)
                Try
                    chemsList = SelectedMaterial.SkladChemiczny.OrderByDescending(Function(x) Decimal.Parse(x.Wartosc, CultureInfo.InvariantCulture)).ToList()
                Catch ex As Exception
                    chemsList = SelectedMaterial.SkladChemiczny
                End Try

                For Each chemicalComposition As SkladChemiczny In chemsList
                    wireCertificate.ChemicalComposition.Add(
                        New WireCertificateChemicalComposition With {
                            .ElementAmount = chemicalComposition.Wartosc,
                            .ElementName = chemicalComposition.Sklad.Pierwiastek.Nazwa,
                            .WireCertificate = wireCertificate
                        })
                Next
            End If

            Dim wireCertificateWireSelectionDialog As New WireCertificateWireSelectionDialog(_wysylka, SelectedOrderLine, SelectedMaterial, SelectedWires, wireCertificate, Me, _unitOfWork)
            Me.Hide()
            wireCertificateWireSelectionDialog.ShowDialog()


        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Sub dgv_PozycjeZlecenia_CellContentClick(sender As System.Object, e As EventArgs) Handles dgv_PozycjeZlecenia.SelectionChanged
        If HasSelectedOrderLineWireCertificate() Then
            btn_ViewWireCertificatePrint.Enabled = True
        Else
            btn_ViewWireCertificatePrint.Enabled = False
        End If
    End Sub

    Private Function HasSelectedOrderLineWireCertificate() As Boolean
        For Each row As DataGridViewRow In dgv_PozycjeZlecenia.SelectedRows
            If CType(row.Cells("WireCertificate").Value, Boolean) Then
                Return True
            End If
        Next
        Return False
    End Function

    Private Sub btn_ViewWireCertificatePrint_Click(sender As System.Object, e As System.EventArgs) Handles btn_ViewWireCertificatePrint.Click
        Try
            EnsureOrderLineIsSelected()
            If Not HasSelectedOrderLineWireCertificate() Then
                Throw New Exception("Wybrana pozycja zlecenia nie posiada wygenerowanego świadectwa.")
            End If

            Dim tag As Tuple(Of PozycjaZlecenia, Material) = CType(dgv_PozycjeZlecenia.SelectedRows(0).Tag, Tuple(Of PozycjaZlecenia, Material))
            Dim wireCertificate As WireCertificate = tag.Item1.WireCertificates.FirstOrDefault(Function(x) x.Shipment.Id = _wysylka.Id AndAlso x.Material.Id = tag.Item2.Id)
            Dim printingDialog As New WireCertificatePrintingDialog(wireCertificate, Me, _unitOfWork)
            Me.Hide()
            printingDialog.ShowDialog()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub
End Class